
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;


public class Mash {
	private final int cap;
	private List<Knoten> kList;
//	private static int mashCounter; 
	private final int mashID;
	private boolean stable;
    private RWLock rwLock = new RWLock();
	
	public Mash(int cap){
		this.cap = cap;
		kList = new CopyOnWriteArrayList<Knoten>();
		mashID= netz2135.mashCounter.getNextId();
		setUnstable();
	}
	
	public Mash(int cap, List<Knoten> neu){
		this.cap = cap;
		this.kList = new CopyOnWriteArrayList<Knoten>();
		mashID= netz2135.mashCounter.getNextId();
		setUnstable();
		for (Knoten knoten : neu){
			this.add(knoten);
		}
	}
	
	
	public void add(Knoten k){
		rwLock.startWriting();
		try{
		kList.add(k);
		k.setMash(this);
		}finally{
			rwLock.endWriting();
		}
	}

	public List<Knoten> getkList() {
		rwLock.startReading();
		try{
			return kList;
		}finally {
			rwLock.endReading();
		}
	}

	public int getCap() {
		rwLock.startReading();
		try{
		return cap;
		}finally {
			rwLock.endReading();
		}
	}

	public void removeKnList(List<Knoten> toRemove){
		
			rwLock.startWriting();
		try{
		for(Knoten k : toRemove){
			//TODO just for debug
			if(!kList.contains(k)) throw new IllegalStateException("Node cant be removed, because isnt in this Mash");
			if(kList.size()<=1) throw new IllegalStateException("GAYLORD");
			kList.remove(k);
			
		}
		}finally {
			rwLock.endWriting();
		}
		
	}
	
	public boolean zeigtAufMash(Knoten tocheck){
		rwLock.startReading();
		try{
			for(Knoten k:kList){
				if(tocheck.getNachfolger().contains(k)){
					return true;
					
				}
			}
//		for (Knoten k : kList){
//				for(Knoten akt : k.getVorganger()){
//					if(tocheck.equals(akt)) return true;
//				}
//		}
		return false;
		}finally {
			rwLock.endReading();
		}
	}
	
	
	@Override
	public String toString(){
		rwLock.startReading();
		try{
		StringBuffer sb = new StringBuffer();
		for (Knoten k : kList){
			sb.append("" + k + "");
		}
		return sb.toString();
		}finally {
			rwLock.endReading();
		}
	}
	
//	private int getMashCount(){  			//thread-save operation
//		return mashCounter++;
//	}

	public int getMashID() {
		rwLock.startReading();
		try{
		return mashID;
		}finally {
			rwLock.endReading();
		}
	}

	public void setStable() {
		rwLock.startWriting();
		try{
		this.stable = true;
		netz2135.unstable.remove(this);
		}finally {
			rwLock.endWriting();
		}
	}
	
	public void setUnstable() {
		rwLock.startWriting();
		try{
		this.stable = false;
		netz2135.unstable.add(this);
		}finally {
			rwLock.endWriting();
		}
	}

	public boolean isStable() {
		rwLock.startWriting();
		try{
		return stable;
	}finally {
		rwLock.endWriting();
	}
	}
}
